//--------------------------------------------------------------------------------------------------------------
// <copyright file="CSPProcedureWebPart.cs" company="Microsoft Corporation" author="David Martos" date="01/02/2008">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//--------------------------------------------------------------------------------------------------------------
using System;
using System.Data;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml;
using System.Xml.XPath;
using CSP.Core;
using CSP.MembershipInterface.ObjectModel;
using Microsoft.Office.InfoPath.Server.Controls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;

//using CSP.Integration;

namespace CSP.WebParts
{
    /// <summary>
    /// This webpart gets the list of online procedures
    /// </summary>
    [Guid("D67914CB-34EC-448a-A35B-45B7D7C04F7F")]
    public class CSPProcedureWebPart : BaseWebPart, IPostBackEventHandler 
    {
        #region member
        private const string XsnLocationVariable = "XsnLocation";
        private const string ProcedureTitleVariable = "ProcedureTitle";
        CaseType[] caseTypes = null;
        DataTable caseTypesTable = new DataTable();
        private UserControls.CSPProceduresWUC control;
        protected XmlFormView formView = null;
        #endregion

        #region properties
        private string introMessage;
        [Personalizable(PersonalizationScope.Shared)]
        [WebBrowsable(true)]
        [ResourcesAttribute("IntroMessageDisplayName", "CSPWebPartParameterCategory", "IntroMessageDescription")]
        public string IntroMessage
        {
            get { return this.introMessage; }
            set { this.introMessage = value; }
        }

        #endregion

        #region methods
        /// <summary>
        /// Constructor
        /// </summary>
        public CSPProcedureWebPart()
        {
            this.ExportMode = WebPartExportMode.All;
        }

      
        /// <summary>
        /// Fired on page create child control, loads the ASCX file
        /// </summary>
        protected override void CreateChildControls()
        {
            base.CreateChildControls();

            try
            {
                if (CSP.Core.MembershipHelper.IsCurrentUserCitizen())
                {
               
                    this.Hidden = false;

                    // The FileUpload control is added to the controls list to add the
                    // enctype="multipart/form-data" automatically to the page where
                    // the webpart is added.
                    FileUpload fu = new FileUpload();
                    this.Controls.Add(fu);

                    // CSPProceduresWUC contains the list of webparts to be shown
                    control = (UserControls.CSPProceduresWUC)Page.LoadControl(WebPartConstants.CSPProceduresWUC);
                    control.WrapperWebPart = this;
                    this.BindData();    
                    this.Controls.Add(control);

                    // formView is the Form Server wrapper webpart.
                    formView = new XmlFormView();
                    formView.Width = System.Web.UI.WebControls.Unit.Percentage(100);
                    this.Controls.Add(formView);
                }
                else
                {
                    this.Hidden = true;
                }
            }
            catch (CSP.Core.CSPException cspex)
            {
                errors.Add(this.LoadResource(WebPartConstants.CSPGenericErrorMessage));
            }
            catch (Exception ex)
            {
                this.LogMessage(this.LoadResource(WebPartConstants.CSPProceduresLoadErrorMessage), this.GetType().Name, ex);
                errors.Add(this.LoadResource(WebPartConstants.CSPGenericErrorMessage));
            }
        }


        /// <summary>
        /// Loads the data stored in the data source
        /// </summary>
        private void BindData()
        {
            SPSecurity.RunWithElevatedPrivileges(delegate(){
            CSP.MembershipInterface.MembershipServiceClient client = null;

            try
            {
                client = new CSP.MembershipInterface.MembershipServiceClient();
                caseTypes = client.GetCaseTypes();
                client.Close();

                string xml = "<procedures>";

                foreach (CaseType type in caseTypes)
                {
                    xml += string.Format("<procedure><title>{0}</title><url>{1}</url></procedure>", type.CaseTypeTitle, Page.ClientScript.GetPostBackClientHyperlink(this, type.CaseTypeCode + "|" + type.CaseTypeTitle));
                }

                xml += "</procedures>";

                control.DataSource = xml;
            }
            catch (Exception ex)
            {
                this.LogMessage(this.LoadResource(WebPartConstants.CSPProceduresLoadErrorMessage), this.GetType().Name, ex);
                throw new CSP.Core.CSPException(ex);
            }
            finally
            {
                if (client != null && client.State != System.ServiceModel.CommunicationState.Closed)
                    client.Close();
            }
            });

        }

        /// <summary>
        /// Fired on page prerender
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            try
            {
                if (CSP.Core.MembershipHelper.IsCurrentUserCitizen())
                {

                    string xsnlocation = string.Empty;
                    if (ViewState[XsnLocationVariable] != null)
                    {
                        if (ViewState[ProcedureTitleVariable] != null)
                            this.Title = ViewState[ProcedureTitleVariable].ToString();

                        SPSite webCollection = Microsoft.SharePoint.WebControls.SPControl.GetContextSite(Context);
                        xsnlocation = ViewState[XsnLocationVariable].ToString();

                        formView.XsnLocation = string.Format(Constants.FormViewerParamTemplateNameFormatURL, webCollection.Url, xsnlocation);
                        formView.ShowHeader = false;
                        formView.ShowFooter = false;

                        formView.EditingStatus = XmlFormView.EditingState.Editing;
                        formView.Initialize += new EventHandler<InitializeEventArgs>(formView_Initialize);
                        // formView.NotifyHost += new EventHandler<NotifyHostEventArgs>(formView_NotifyHost);
                        formView.SubmitToHost += new EventHandler<SubmitToHostEventArgs>(formView_SubmitToHost);

                    }
                }
            }
            catch (CSPException cspex)
            {
                errors.Add(this.LoadResource(WebPartConstants.CSPGenericErrorMessage));
            }
            catch (Exception ex)
            {
                LogMessage(WebPartConstants.CSPProceduresLoadErrorMessage, this.GetType().Name, ex);
                errors.Add(this.LoadResource(WebPartConstants.CSPGenericErrorMessage));
            }
        }
        
        /// <summary>
        /// Firen on page render
        /// </summary>
        /// <param name="writer"></param>
        protected override void Render(HtmlTextWriter writer)
        {
            try
            {
                if (errors.Count > 0)
                    base.Render(writer);
                else
                {
                    if (CSP.Core.MembershipHelper.IsCurrentUserCitizen())
                    {

                        if (Page.IsPostBack)
                        {
                            formView.RenderControl(writer);
                        }
                        else
                        {
                            if (caseTypes.Length == 0)
                            {
                                writer.Write(LoadResource(WebPartConstants.CSPEmptyListMessage));
                            }
                            else
                            {
                                if (introMessage!=string.Empty)
                                    writer.Write(string.Format("<div class=\"ProceduresIntro\">{0}</div>", introMessage));
                                control.RenderControl(writer);
                            }
                        }
                    }
                }
            }
            catch (CSPException cspex)
            {
                errors.Add(this.LoadResource(WebPartConstants.CSPGenericErrorMessage));
            }
            catch (Exception ex)
            {
                LogMessage(WebPartConstants.CSPProceduresLoadErrorMessage, this.GetType().Name, ex);
                errors.Add(this.LoadResource(WebPartConstants.CSPGenericErrorMessage));
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="eventArgument"></param>
        public void RaisePostBackEvent(string eventArgument)
        {
            string[] arguments = eventArgument.Split("|".ToCharArray());
            ViewState.Add(XsnLocationVariable, arguments[0]);
            ViewState.Add(ProcedureTitleVariable, arguments[1]);
        }

        /// <summary>
        /// Fired when the form is sent
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void formView_SubmitToHost(object sender, SubmitToHostEventArgs e)
        {
            try
            {
                XPathNavigator xNavMain = formView.XmlForm.MainDataSource.CreateNavigator();
                XmlNamespaceManager manager = formView.XmlForm.NamespaceManager;



                CSP.MembershipInterface.MembershipServiceClient client = null;

                Case crmCase = new Case();
                crmCase.CreatedDate = DateTime.Now;
                crmCase.Description = xNavMain.SelectSingleNode(Constants.XPathRequestTitle, manager).Value;
                crmCase.DueDate = DateTime.Now.AddDays(30); // TODO: What is Due Date?
                crmCase.ExternalDocumentRef = string.Empty; // TODO: Assign the URL with additional information
                crmCase.FormXml = xNavMain.OuterXml;
                crmCase.ID = xNavMain.SelectSingleNode(Constants.XPathRequestIdentificator, manager).Value;
                crmCase.LastModified = DateTime.Now;
                crmCase.OwnerID = string.Empty; // TODO: Assign a civil servant username
                crmCase.RequestorAddress = xNavMain.SelectSingleNode(Constants.XPathCitizenAddress, manager).Value;
                crmCase.RequestorCity = xNavMain.SelectSingleNode(Constants.XPathCitizenCity, manager).Value;
                crmCase.RequestorEmail = xNavMain.SelectSingleNode(Constants.XPathCitizenEmail, manager).Value;
                crmCase.RequestorID = xNavMain.SelectSingleNode(Constants.XPathCitizenID, manager).Value;
                crmCase.RequestorName = xNavMain.SelectSingleNode(Constants.XPathCitizenName, manager).Value;
                crmCase.RequestorPhone = xNavMain.SelectSingleNode(Constants.XPathCitizenPhone, manager).Value;
                crmCase.RequestorPostalCode = xNavMain.SelectSingleNode(Constants.XPathCitizenZip, manager).Value;
                crmCase.Title = xNavMain.SelectSingleNode(Constants.XPathRequestTitle, manager).Value; 

                try
                {
                    client = new CSP.MembershipInterface.MembershipServiceClient();
                    crmCase.Type = client.GetCaseTypeByName(ViewState[XsnLocationVariable].ToString());
                    crmCase.RoleType = client.GetInitialCaseRoleType();
                    crmCase.Status = client.GetInitialCaseStatus();
                    string result = client.AddCase(crmCase);                                       
                    client.Close();
                    if (result == null)
                    {
                        errors.Add(this.LoadResource(WebPartConstants.CSPProceduresAddKO));
                        WrapperWebPart.AddError(LoadResource(WebPartConstants.CSPProceduresAddKO));
                    }
                 
                }
                catch (Exception ex)
                {
                    this.LogMessage(this.LoadResource(WebPartConstants.CSPProceduresLoadErrorMessage), this.GetType().Name, ex);
                    errors.Add(this.LoadResource(WebPartConstants.CSPGenericErrorMessage));
                }
                finally
                {
                    if (client != null && client.State != System.ServiceModel.CommunicationState.Closed)
                        client.Close();
                }
            }
            catch (Exception ex)
            {
                LogMessage(WebPartConstants.CSPProceduresLoadErrorMessage, this.GetType().Name, ex);
                errors.Add(this.LoadResource(WebPartConstants.CSPGenericErrorMessage));
            }
        }

        /// <summary>
        /// Initializes the infopath form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void formView_Initialize(object sender, InitializeEventArgs e)
        {
            try
            {
                InitializeForm();
            }
            catch (Exception ex)
            {
                errors.Add(this.LoadResource(WebPartConstants.CSPGenericErrorMessage));
                throw new CSP.Core.CSPException(ex);
            }
        }

        /// <summary>
        /// Fills all the infopath fields related to the Contoso citizen
        /// </summary>
        protected virtual void FillForm()
        {

            XPathNavigator xNavMain = formView.XmlForm.MainDataSource.CreateNavigator();
            XmlNamespaceManager manager = formView.XmlForm.NamespaceManager;
            string loginname = string.Empty;

            loginname = Context.User.Identity.Name;

            string name = string.Empty;
            string address = string.Empty;
            string city = string.Empty;
            string zip = string.Empty;
            string phone = string.Empty;
            string contactid = string.Empty;
            string email = string.Empty;

            Citizen citizen = new Citizen();
            CSP.MembershipInterface.MembershipServiceClient client = null;

            try
            {
                client = new CSP.MembershipInterface.MembershipServiceClient();
                citizen = client.GetCitizenByUsername(loginname);
                client.Close();
            }
            catch (Exception ex)
            {
                LogMessage(WebPartConstants.CSPEndPointErrorMessage, this.GetType().Name, ex);
                throw new CSP.Core.CSPException(ex);
            }
            finally
            {
                if (client != null && client.State != System.ServiceModel.CommunicationState.Closed)
                    client.Close();
            }

            if (citizen.EmailAddress!=null)
                email = citizen.EmailAddress;
            else
                email = "";

            if (citizen.DisplayName != null)
                name = citizen.DisplayName;
            else
                name = "";

            if (citizen.Address != null)
                address = citizen.Address;
            else
                address = "";

            if (citizen.City != null)
                city = citizen.City;
            else
                city = "";

            if (citizen.PostalCode != null)
                zip = citizen.PostalCode;
            else
                zip = "";

            if (citizen.Phone != null)
                phone = citizen.Phone;
            else
                phone = "";

            if (citizen.Username != null)
                contactid = citizen.Username;
            else
                contactid = "";

         
            

            xNavMain.SelectSingleNode(Constants.XPathRequestIdentificator, manager).SetValue(System.Guid.NewGuid().ToString());

            xNavMain.SelectSingleNode(Constants.XPathCitizenName, manager).SetValue(name);
            xNavMain.SelectSingleNode(Constants.XPathCitizenAddress, manager).SetValue(address);
            xNavMain.SelectSingleNode(Constants.XPathCitizenCity, manager).SetValue(city);
            xNavMain.SelectSingleNode(Constants.XPathCitizenZip, manager).SetValue(zip);
            xNavMain.SelectSingleNode(Constants.XPathCitizenPhone, manager).SetValue(phone);
            xNavMain.SelectSingleNode(Constants.XPathCitizenEmail, manager).SetValue(email);
            xNavMain.SelectSingleNode(Constants.XPathCitizenID, manager).SetValue(contactid);

        }

        /// <summary>
        /// Translates the inforpath form template with the information found on the Contoso Central
        /// Translation library
        /// </summary>
        protected virtual void TranslateForm()
        {

            try
            {
                XPathNavigator xNavMain = formView.XmlForm.MainDataSource.CreateNavigator();
                XmlNamespaceManager manager = formView.XmlForm.NamespaceManager;

                // For every label in the datasource, we translate the expression box
                XPathNavigator labels = xNavMain.SelectSingleNode(Constants.XPathLabelsNode, manager);

                if (labels != null)
                {

                    XPathNodeIterator iterator = labels.SelectChildren(XPathNodeType.Element);
                    while (iterator.MoveNext())
                    {
                        iterator.Current.SetValue(LoadResource(iterator.Current.LocalName));
                    }
                }

                // For every list in the form datasource, we populate the combobox with the translated literals
                XPathNavigator lists = xNavMain.SelectSingleNode(Constants.XPathListsNode, manager);

                if (lists != null)
                {

                    XPathNodeIterator iterator = lists.SelectChildren(XPathNodeType.Element);
                    while (iterator.MoveNext())
                    {
                        string options = LoadResource(iterator.Current.LocalName);
                        string listXPath = iterator.Current.Value;

                        XPathNavigator list = xNavMain.SelectSingleNode(listXPath, manager);
                        string[] optionsArray = options.Split(";".ToCharArray());
                        XPathNavigator elementNode = list.SelectSingleNode("*");

                        for (int i = 0; i < optionsArray.Length; i++)
                        {
                            list.AppendChildElement(elementNode.Prefix, elementNode.LocalName, elementNode.NamespaceURI, optionsArray[i]);
                        }

                        elementNode.DeleteSelf();
                    }
                }
            }
            catch (Exception ex)
            {
                LogMessage(WebPartConstants.CSPProceduresTraductionErrorMessage, this.GetType().Name, ex);
            }


        }
        /// <summary>
        /// Prepopulates the form. You can override this method to customizate this pre-population
        /// </summary>
        protected void InitializeForm()
        {
            string email = string.Empty;

            try
            {
                FillForm();
                TranslateForm();
            }
            catch (CSP.Core.CSPException cspex)
            {
                errors.Add(this.LoadResource(WebPartConstants.CSPGenericErrorMessage));
            }
            catch (Exception ex)
            {
                formView.XmlForm.MainDataSource.CreateNavigator().SelectSingleNode(Constants.XPathRequestMessage, formView.XmlForm.NamespaceManager).SetValue(ex.Message);
                LogMessage(WebPartConstants.CSPProceduresLoadErrorMessage, this.GetType().Name, ex);
                errors.Add(this.LoadResource(WebPartConstants.CSPGenericErrorMessage));
            }
        }

        #endregion
    }
}
